package com.epcs.controller.action;

import java.io.InputStream;
import java.io.StringBufferInputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.apache.struts2.dispatcher.SessionMap;
import org.apache.struts2.interceptor.ServletRequestAware;
import org.apache.struts2.interceptor.SessionAware;

import com.epcs.model.bo.EmailBO;
import com.epcs.model.bo.SynchronizationBO;
import com.epcs.model.dto.Account;
import com.epcs.model.dto.Email;
import com.opensymphony.xwork2.Action;
import com.opensymphony.xwork2.ActionSupport;

public class SynchronizationAction extends ActionSupport implements SessionAware, ServletRequestAware {

	// ---------- input fields ----------//
	private String chooseGoogleCalendar;
	private String chooseOutlookCalendar;
	private String choosingFor;
	private SessionMap<String, Object> sessionMap;
	private HttpServletRequest request;
	private InputStream inputStream;

	// ----------Action method -----------//

	public String execute() {
		SynchronizationBO syncBO = new SynchronizationBO();
		String resultString = "Running";
		Account account = (Account) sessionMap.get("USER_INFO");
		String syncStatus = (String) sessionMap.get("SYNC_STATUS");
		boolean acceptToSync = false;
		try {
			// chỉ cho sync khi sync chưa chạy
			if (syncStatus == null){
				acceptToSync = true;
			} else {
				if (!syncStatus.equals("Running")){
					acceptToSync = true;				
				} else {
					inputStream = new StringBufferInputStream("RunningBefore");
				}
			}
			if (acceptToSync) {
				// kiểm tra xem có session, login chưa
				if (account != null) {
					
					// check email của user có thỏa yêu cầu trước khi sync không
					int result = syncBO.checkEmailBeforeSync(account);
					
					if (result == -1) {// chua có đăng ký email nào				
						request.setAttribute("WARNING_MESSAGE", "Bạn chưa đăng ký email để đồng bộ!");
						resultString = "Unregister_Email";
						
					} else if (result == -2) {
						// chọn calendar name để mà đồng bộ -- tương tự như lần đầu đồng bộ
						
						// lấy danh sách các calendar tương ứng với email cho user chọn
						Map<String, Map<String, List>> calendarMap = new SynchronizationBO()
								.getAllCalendarForChoosing(account);
						// gởi danh sách về cho user chọn
						request.setAttribute("ALL_CALENDAR_NEED_TO_CHOOSE", calendarMap);
						resultString = "ChooseCalendar";
						
					} else if (result == 1) {
						// tạo thread chạy
						SynchronizationThread syncObject = new SynchronizationThread(account, sessionMap);
						Thread syncThread = new Thread (syncObject);
						// run thread
						syncThread.start();
						sessionMap.put("SYNC_STATUS", "Running");
						inputStream = new StringBufferInputStream("Running");
						resultString = "Running";
					}
					
				} else {// chua có session của user
					inputStream = new StringBufferInputStream("Unauthorized");
				}
			}
		} catch (Exception e) {
			sessionMap.remove("SYNC_STATUS");
			resultString = "Fail";
		}
		
		return resultString;
	}

	public String checkSynchronization(){
		Account account = (Account) sessionMap.get("USER_INFO");
		String syncStatus = (String) sessionMap.get("SYNC_STATUS");
		
		if (account != null){
			if (syncStatus != null) {
				if (syncStatus.equals("Success")) {
					// success
					inputStream = new StringBufferInputStream("Success");
					sessionMap.remove("SYNC_STATUS");
				} else if (syncStatus.equals("Fail")) {
					// fail
					inputStream = new StringBufferInputStream("Fail");
					sessionMap.remove("SYNC_STATUS");
				} else {
					// running
					inputStream = new StringBufferInputStream("Running");
				}
			} else {
				inputStream = new StringBufferInputStream("NotSync");
			}
		} else {
			inputStream = new StringBufferInputStream("Unauthorized");
		}
		
		return Action.SUCCESS;
	}
	
	/**
	 * method được dùng cho sync lần đầu Sau khi user chọn các calendar cần thiết cho việc đồng bộ
	 * hệ thống nhận và xử lý
	 * 
	 * @return
	 */
	public String chooseCalendar() {
		String resultString = "Fail";
		SynchronizationBO bo = new SynchronizationBO();
		Account account = (Account) sessionMap.get("USER_INFO");

		// kiểm tra session đã login chưa
		if (account != null) {

			// bắt đầu gọi method cho việc sync lần đầu tiên
			// NOTE: chooseCalendar là danh sách các calendar đã chọn tương ứng với từng email
			// objectReconstruction là method tái cấu trúc lại danh sách về dạng đã được phân loại theo service
			// synchronizeFortheFirstTime là method để bắt đầu sync lần đầu
			List<String> chooseCalendarList = new ArrayList<String>();
			chooseCalendarList.add(chooseGoogleCalendar);
			chooseCalendarList.add(chooseOutlookCalendar);
			// remove null là dùng cho đồng bộ 1 loại service
			chooseCalendarList.remove(null);
			
			
			String[] chooseCalendar = chooseCalendarList.toArray(new String[0]);
			System.out.println("chooseGoogleCalendar = " + chooseGoogleCalendar);
			System.out.println("chooseOutlookCalendar = " + chooseOutlookCalendar);
			System.out.println("chooseCalendar = " + chooseCalendar.length);
			
			boolean result = bo.synchronizeFortheFirstTime(account, bo.objectReconstruction(account, chooseCalendar));

			if (result) {
				resultString = "Success";
				// quay về trang index
			} else {
				request.setAttribute("ERROR_TYPE", "syncError");
			}
		} else {// chưa login
			resultString = "Unauthorized";
		}

		return resultString;
	}

	// -----------Getter and Setter -----//

	public String getChooseGoogleCalendar() {
		return chooseGoogleCalendar;
	}

	public void setChooseGoogleCalendar(String chooseGoogleCalendar) {
		this.chooseGoogleCalendar = chooseGoogleCalendar;
	}

	public String getChooseOutlookCalendar() {
		return chooseOutlookCalendar;
	}

	public void setChooseOutlookCalendar(String chooseOutlookCalendar) {
		this.chooseOutlookCalendar = chooseOutlookCalendar;
	}

	public String getChoosingFor() {
		return choosingFor;
	}

	public void setChoosingFor(String choosingFor) {
		this.choosingFor = choosingFor;
	}

	public InputStream getInputStream() {
		return inputStream;
	}

	public void setInputStream(InputStream inputStream) {
		this.inputStream = inputStream;
	}
	// ---------------- session --------------------//
	@Override
	public void setSession(Map<String, Object> sessionMap) {
		this.sessionMap = (SessionMap<String, Object>) sessionMap;
	}

	@Override
	public void setServletRequest(HttpServletRequest request) {
		this.request = request;

	}



}
